package kompics.ring;

import kompics.ring.components.SimplePeer;
import kompics.ring.events.PeerContInit;
import kompics.ring.events.ReadValueEvent;
import kompics.ring.events.StoreKeyEvent;

import se.sics.kompics.Component;
import se.sics.kompics.ComponentDefinition;
import se.sics.kompics.Kompics;
import se.sics.kompics.address.Address;
import se.sics.kompics.launch.Topology;
import se.sics.kompics.network.Network;
import se.sics.kompics.network.mina.MinaNetwork;
import se.sics.kompics.network.mina.MinaNetworkInit;

/**
 * @author shadid
 * 
 */
public class MainContainer extends ComponentDefinition {

	private static int selfId;
	Topology topology = Topology.load(System.getProperty("topology"), selfId);

	public static void main(String[] args) {
		selfId = Integer.parseInt(args[0]);
		Kompics.createAndStart(MainContainer.class, 8);
	}

	public MainContainer() throws InstantiationException, IllegalAccessException {

		Address self = topology.getSelfAddress();
		Address successor = getSuccessor(selfId, topology);

		// Component creation
		Component sPeer = create(SimplePeer.class);
		Component network = create(MinaNetwork.class);

		// Connections between components
		connect(sPeer.getNegative(Network.class),
				network.getPositive(Network.class));

		// firing inits
		trigger(new MinaNetworkInit(self), network.getControl());
		trigger(new PeerContInit(null, successor, self), sPeer.getControl());

		// Test events
		// Some messages might drop because nodes will different
		// sequence and if an event is fired before a node is started then these
		// are likely to be lost
		if(self.getId() == 4)
		{
			trigger(new StoreKeyEvent(self, self, 30, 559), sPeer.getNegative(Network.class));
			trigger(new StoreKeyEvent(self, self, 340, 49), sPeer.getNegative(Network.class));
		}
		
		if(self.getId() == 3)
		{
			trigger(new ReadValueEvent(self, self, 30), sPeer.getNegative(Network.class));
			trigger(new ReadValueEvent(self, self, 340), sPeer.getNegative(Network.class));
		}
		
	}
	
	Address getSuccessor(int selfId, Topology topology)
	{
		// hackish implementation for now
		int successorId = (selfId % topology.getNodeCount()) + 1;

		return topology.getAddress(successorId);
		
	}

}
